#pragma once

#include <string>
#include <map>
#include <list>
#include <ostream>

#include "Value.h"

using namespace std;
using namespace utility::common;

namespace utility{
namespace xml{

class Xml
{
public:
    Xml();
    Xml(const char * name);
    Xml(const string & name);
    Xml(const Xml & other);

    string name() const;
    void name(const string & name);

    string text() const;
    void text(const string & text);

    Value & attr(const string & key);
    void attr(const string & key, const Value & value);

    Xml & operator = (const Xml & other);

    void append(const Xml & child);
    Xml & operator [] (int index);
    Xml & operator [] (const char * name);
    Xml & operator [] (const string & name);

    void remove(int index);
    void remove(const char * name);
    void remove(const string & name);

    int size() const;

    void clear();

    string str() const;

    typedef std::list<Xml>::iterator iterator;
    iterator begin()
    {
        return m_child->begin();
    }
    iterator end()
    {
        return m_child->end();
    }
    iterator erase(iterator it)
    {
        it->clear();
        return m_child->erase(it);
    }

    bool load(const string & filename);
    bool save(const string & filename);
    bool parse(const string & str);

    friend ostream & operator << (ostream & os, const Xml & xml)
    {
        os << xml.str();
        return os;
    }

private:
    string * m_name;
    string * m_text;
    std::map<string, Value> * m_attrs;
    std::list<Xml> * m_child;
};
}
}
